package org.byd.dmsja.controller.applogin;

import org.byd.dmsja.entity.DmsMenuDbEx;
import org.byd.dmsja.entity.DmsParaDb;
import org.byd.dmsja.entity.DmsUserDb;
import org.byd.dmsja.service.DmsMenuService;
import org.byd.dmsja.service.DmsParaService;
import org.byd.dmsja.service.DmsUserService;
import org.byd.dmsja.utils.JWTUtils;
import org.byd.dmsja.utils.SNEHierData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

@CrossOrigin
@RestController
public class AppLoginController {

    @Autowired
    private DmsUserService dmsUserService;
    @Autowired
    private DmsMenuService dmsMenuService;


    public static class CDoCheckPIn {
        public DmsUserDb loginInfo = new DmsUserDb();
    }

    public static class CDoCheckPOut {
        public String errMsg = "";
        public DmsUserDb loginUser = new DmsUserDb();
        public String token = "";
        public List<DmsMenuDbEx> menuList = new ArrayList<>();
    }

    @PostMapping("/applogin/doCheck")
    public CDoCheckPOut doCheck(@RequestBody CDoCheckPIn in) {
        CDoCheckPOut out = new CDoCheckPOut();
        try {
            out.loginUser = dmsUserService.findUserByUserId(in.loginInfo.user_id); if (out.loginUser == null) {
                out.errMsg = "用户不存在";
            } else if (!out.loginUser.user_pwd.equals(in.loginInfo.user_pwd)) {
                out.errMsg = "密码错误";
            } else {
                Map<String, String> map = new HashMap<>();
                map.put("user_id", out.loginUser.user_id);
                map.put("user_name", out.loginUser.user_name);
                out.token = JWTUtils.genToken(map);
                out.loginUser.user_pwd = ""; var tmpMenuList = dmsMenuService.findAllMenu();
                var menuListEx = tmpMenuList.stream().map(x -> {
                    var ex = new DmsMenuDbEx();
                    ex.tid = (x.tid);
                    ex.pid = (x.pid);
                    ex.no = (x.no);
                    ex.title = (x.title == null ? "" : x.title.trim());
                    ex.desx = (x.desx);
                    ex.icon_cls = (x.icon_cls);
                    ex.prog_id = (x.prog_id);
                    ex.prog_cover = (x.prog_cover);
                    ex.exts = (x.exts);
                    ex.disabled = (x.disabled == null ? 0 : x.disabled);
                    ex.disabled = (!Objects.equals(x.disabled, 0) ? 1 : x.disabled);
                    ex.for_roles = (x.for_roles);
                    ex.cache_if = (x.cache_if);
                    ex.close_if = (x.close_if);
                    ex.can_access = 0;
                    ex.title_path = "";
                    return ex;
                }).collect(Collectors.toList());
                out.menuList = menuListEx;
                this.doCheck_Adjust(out);
                var x = 1;
            }
        } catch (Exception ex) {
            out.errMsg = ex.getMessage();
        } return out;
    }

    private void doCheck_Adjust(CDoCheckPOut out) {
        out.loginUser.user_roles = out.loginUser.user_roles == null ? "" : out.loginUser.user_roles.trim();
        out.loginUser.user_roles = out.loginUser.user_roles.isEmpty() ? "default" : out.loginUser.user_roles;
        var menuListEx = out.menuList.stream().map(x -> {
            x.tid = Objects.isNull(x.tid) ? "" : x.tid.trim();
            x.pid = Objects.isNull(x.pid) ? "" : x.pid.trim();
            x.title = Objects.isNull(x.title) ? "" : x.title.trim();
            x.for_roles = Objects.isNull(x.for_roles) ? "" : x.for_roles.trim(); return x;
        }).collect(Collectors.toList());
        var hier = new SNEHierData<DmsMenuDbEx>(menuListEx, x -> x.tid, x -> x.pid);
        var topList = hier.getTopRecordList();
        for (var topItem : topList) {
            hier.forEachChildAll(topItem, x -> {
                if (Objects.equals(topItem.disabled, 1)) {
                    x.disabled = 1;
                }
            });
        } for (var menuItemEx : hier.recordList) {
            menuItemEx.can_access = this.doCheck_CanAccess(out.loginUser, menuItemEx);
        }

        var deepList = hier.getDeepRecordList();
        for (var menuItemEx : deepList) {
            hier.forEachParentAll(menuItemEx, x -> {
                if (Objects.equals(x.can_access, 1)) {
                    menuItemEx.can_access = 1;
                }
            });
        }

        for (var menuItemEx : hier.recordList) {
            var titlePath = hier.getPath(menuItemEx, x -> x.title);
            menuItemEx.title_path = titlePath;
        }

        out.menuList = hier.recordList.stream()
                .filter(x -> Objects.equals(x.can_access, 1))
                .collect(Collectors.toList());
    }

    private Integer doCheck_CanAccess(DmsUserDb userItem, DmsMenuDbEx menuItemEx) {
        var ret = 0; if (Objects.equals(menuItemEx.disabled, 1)) {
            ret = 0;
        } else {
            List<String> userRoles =
                    Arrays.stream(userItem.user_roles.split(",")).map(x -> x.trim()).collect(Collectors.toList());
            List<String> menuRoles =
                    Arrays.stream(menuItemEx.for_roles.split(",")).map(x -> x.trim()).collect(Collectors.toList());
            List<String> intesectRoles = menuRoles.stream().filter(x -> {
                return userRoles.stream().anyMatch(y -> Objects.equals(x, y));
            }).collect(Collectors.toList()); ret = intesectRoles.size() > 0 ? 1 : 0;
        } return ret;
    }


}
